Harden Python preview collection, lifetime, interface, and async safety - #198
Open
leileizhang (lei9444) wants to merge 15 commits into
Open
leileizhang (lei9444) wants to merge 15 commits into
leileizhang (lei9444) wants to merge 15 commits into
Conversation
Validate the receiver's stock runtime-class contract before JSON value writes, preflight bulk mutations, and keep custom generic collections nullable. Narrow verified stock class stubs and test real native behavior and strict consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Register owned native results at Python return boundaries so a closing scope releases raw values before apartment teardown, while preserving borrowed sources, scalar results, callback thread affinity, and released-value errors. Reproduce and guard the shutdown crash in subprocesses. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
QueryInterface-check standalone constructors before retaining or caching a pointer, preserve borrowed constructor sources on cache hits, and fail closed for unknown IIDs. Keep generic and observable projections safe with real WinRT and strict typing regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Require an Object before call_0/call_1 can prepare or dispatch a caller-specified native signature. Exercise pre-dispatch rejection and valid IID-cast low-level calls in an isolated Python process. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe raw outputs weakly so temporary casts and callback inputs drop without accumulating native references; keep projected wrappers strongly tracked and release surviving raw owners before apartment shutdown. Refresh seven generated Python snapshots for the interface-IID constructor change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mixed-language test coverageWorkflow status: ✅ Passed
|
Match ProjectedLifetimeScope.track_native in the packaged Python stub and test the installed wheel surface, fixing hosted mypy.stubtest parity without changing native lifetime behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Match DynWinRTValue's owned-reference drop in the projection-only test double and accept the checked-constructor cache argument. Assert that an unconsumed temporary returns the native owner's reference count to baseline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Make stock JsonArray/JsonObject runtime method inputs non-null in both normal and --no-pyi output, keeping generic IVector/IMap<IJsonValue> nullable. Verify generated source and inspect.signature contracts without changing JS/TS projections. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Weakly track independent DynWinRTArray and DynWinRTStruct owners at creation, extraction, and nested-field boundaries. Deterministically release surviving COM references at scope exit, reject all post-release access, and leave scalar containers live. Cover five previously crashing subprocess paths, nested arrays, and native reference balance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise get_struct and nested Object-field clones through apartment teardown and owner reference balance, prove releasing a container preserves its external source identity, and verify borrowed native callback arrays survive an inner scope without adopting the parameter. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject mismatched scalar/object and unsupported nested array elements before an ArrayData takes independent ownership. Reuse native WinRT argument validation and typed QueryInterface while preserving null, enum, Char16 and HRESULT aliases. Detect COM owners recursively in actual array payloads as well as declared metadata at every Python tracking boundary; reproduce and prevent both apartment-exit crashes with source-reference balance regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the owned local IStringable fixture for deterministic parallel core tests instead of repeatedly activating cached stock Uri factories across test apartments. Retain stock Uri typed-QI and mismatched-array coverage in an isolated integration executable and Python subprocess, each repeating both paths inside one balanced apartment. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Weakly track raw, container, callback, implementation and async owners so the final managed RoUninitialize releases only their references on the owner thread. Guard cross-thread access and add an explicit callback shutdown gate for embedding hosts, with isolated real-finalization and generated-code regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Initialize the real binding module in both isolated Rust finalization children. Coverage can now exercise native callback owner shutdown without an installed Python wheel, using the same package bootstrap as the embedded-host gate test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reclassify the actual object and nested-struct fields after native setters return, including errors, without masking the original failure. Cover failed agile writes, partial writes, owner-thread balance and successful non-agile transitions on both architectures; document the separate pre-existing reentrant apartment-close limitation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A generated Python WinRT object can outlive
RoApartmentand release its COM reference afterRoUninitialize, crashing the process (#189). Three other preview-safety gaps permit partial JSON mutations, unchecked interface pointers, or an invalid low-level Async receiver (#196).Changes
projected_lifetime_scope(). Balance nested/manual initialization and explicit scopes; do not consume externally owned references. Objects retained past close reportreleasedand reject further use. Unsafe pending async work blocks close for retry rather than being cancelled implicitly.Nonebefore mutating stockJsonArray/JsonObject, including bulk writes and interface views, and align.pyiwith runtime/--no-pyiannotations. UseJsonValue.create_null_value()for JSON null; custom generic collections retain their valid native-null behavior.call_0()/call_1()native dispatch.shutdown_python_callbacks()for embedding hosts. After the host stops new calls and settles in-flight callbacks, it closes Python-backed callback entrypoints beforePy_FinalizeEx; retained native aliases then return a closed error without attaching Python. Apartment cleanup does not revoke external aliases or cancel their work.Verification and boundaries
The original unscoped #189
Urideletion and interpreter-exit reproductions now exit normally on x64 and ARM64. Installed-wheel Python tests, generated WinRT/implementation E2E, strict typing/stubtest, and exact-head Build, mixed-language coverage, and Python-release checks passed. Optional live WinUI fixtures and PR-triggered ARM64 release-wheel jobs are not covered by those hosted checks.This PR does not make reentrant
RoApartment.close()inside a synchronous native callback safe; that pre-existing, separate issue is addressed by #205. A host that skips the explicit callback shutdown protocol has only best-effort protection against external callbacks during the early interpreter-finalization race; no universal guarantee is claimed. If #205 merges first, reconcile apartment-depth and pending-close handling and revalidate the combined result before landing this PR. #189 remains open pending human review and merge; green CI alone is not approval. No release workflow, XML DOM nullability, or published preview.22 notes are changed.